package com.demo;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

public class JVMArgsUtils {
    static MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
    static MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage();
    static String unit = "M";
    private static final int _1MB = 1024 * 1024;
    private byte[] bigSize = new byte[1351 * _1MB];

    public static void main(String[] args) throws InterruptedException {
        getMemoryUsage();
        getRuntimeMemory();
        JVMArgsUtils s = new JVMArgsUtils();
        getCommandLineArgs();
        getRuntimeMemory();
        s = null;
        System.gc();
        Thread.sleep(2000);
        getRuntimeMemory();
        getMemoryUsage();
    }

    /**
     * 查看所有的系统属性,通过-D<名称>=<值>设置，如 java -Dfile.encoding=UTF-8 *.jar/类文件名
     */
    public static void getProperties() {
        Properties properties = System.getProperties();
        Iterator iterator = properties.keySet().iterator();
        while (iterator.hasNext()) {
            String key = (String) iterator.next();
            System.out.println(key + "=" + properties.get(key));
        }
    }

    public static void getCommandLineArgs() {
        System.out.println("---------------------获取传入的JVM参数-------------------------");
        List<String> inputArguments = ManagementFactory.getRuntimeMXBean().getInputArguments();
        System.out.println(inputArguments);
    }

    public static void getRuntimeMemory() {
        System.out.println("---------------------运行时的JVM实时内存-------------------------");
        System.out.println("因为JVM只有在需要内存时才占用物理内存使用，所以空闲内存的值一般情况下都很小，而JVM实际可用内存并不等于空闲内存");
        switch (unit) {
            case "M":
                System.out.println("JVM最大可用内存,对应-Xmx:" + Runtime.getRuntime().maxMemory() / 1024 / 1024 + unit);
                //totalMemory值是慢慢变大的，有需要就从操作系统获得
                System.out.println("JVM当前使用的总内存:" + Runtime.getRuntime().totalMemory() / 1024 / 1024 + unit);
                System.out.println("JVM空闲内存(gc后可能会增大):" + Runtime.getRuntime().freeMemory() / 1024 / 1024 + unit);
                break;
            case "KB":
                System.out.println("JVM最大可用内存,对应-Xmx:" + Runtime.getRuntime().maxMemory() / 1024 + unit);
                System.out.println("JVM当前使用的总内存:" + Runtime.getRuntime().totalMemory() / 1024 + unit);
                System.out.println("JVM空闲内存(gc后可能会增大):" + Runtime.getRuntime().freeMemory() / 1024 + unit);
            default:
                System.out.println("JVM最大可用内存,对应-Xmx:" + Runtime.getRuntime().maxMemory() + unit);
                System.out.println("JVM当前使用的总内存:" + Runtime.getRuntime().totalMemory() + unit);
                System.out.println("JVM空闲内存(gc后可能会增大):" + Runtime.getRuntime().freeMemory() + unit);
        }
    }

    public static final void getMemoryUsage() {
        System.out.println("----------------------------------------------");
        switch (unit) {
            case "M":
                System.out.println("-Xms初始化Java堆大小:" + memoryUsage.getInit() / 1024 / 1024 + unit);
                System.out.println("-Xmx最大Java堆大小,默认物理内存的1/4:" + memoryUsage.getMax() / 1024 / 1024 + unit);
                System.out.println("已使用的内存:" + memoryUsage.getUsed() / 1024 / 1024 + unit);
                System.out.println("提交到JVM的内存:" + memoryUsage.getCommitted() / 1024 / 1024 + unit);
                break;
            case "KB":
                System.out.println(memoryUsage.getInit() / 1024 + unit);
                System.out.println(memoryUsage.getMax() / 1024 + unit);
                System.out.println(memoryUsage.getUsed() / 1024 + unit);
                System.out.println(memoryUsage.getCommitted() / 1024 + unit);
            default:
                System.out.println(memoryUsage.getInit() + unit);
                System.out.println(memoryUsage.getMax() + unit);
                System.out.println(memoryUsage.getUsed() + unit);
                System.out.println(memoryUsage.getCommitted() + unit);
        }
    }
}
